package main

import "fmt"

type calcType func(int, int) int // 自定义一个calc类型
type myInt int

func add(x, y int) int {
	return x + y
}

func sub(x, y int) int {
	return x - y
}

func calc(x, y int, cb func(int, int) int) int { // 等同于func calc(x, y int, cb calcType) int{}
	return cb(x, y)
}

func do(o string) calcType {
	switch o {
	case "+":
		return add
	case "-":
		return sub
	case "*":
		return func(x, y int) int { return x * y }
	case "/":
		return func(x, y int) int { return int(float64(x) / float64(y)) }
	default:
		return nil
	}
}

func main() {
	var c calcType
	c = add                     // 所赋值的函数必须符合类型calc的格式
	fmt.Printf("c的类型: %T\n", c) // c的类型: main.clac
	fmt.Println(c(10, 4))

	// f := sub
	// fmt.Printf("f的类型: %T\n", f) // c的类型: main.clac
	// fmt.Println(f(10, 4))

	// var a int = 1
	// var b myInt = 1
	// fmt.Printf("a的类型是%T,值为%v; b的类型是%T, 值为%v\n", a, a, b, b)
	// fmt.Println(myInt(a) + b)
	// fmt.Println(a + int(b))

	// 函数作为另一个函数参数
	// fmt.Println(calc(10, 5, sub))
	// fmt.Println(calc(10, 5, add))
	// fmt.Println(calc(10, 5, func(x, y int) int { return x * y }))

	// // 函数作为返回值
	var myadd = do("+")
	var mysub = do("-")
	var mymui = do("*")
	var mydiv = do("/")
	fmt.Println(myadd(10, 5))
	fmt.Println(mysub(10, 5))
	fmt.Println(mymui(10, 5))
	fmt.Println(mydiv(10, 5))

	// // 函数嵌套
	// func() {
	// 	fmt.Println("这是一个嵌套匿名自执行函数的打印。。。")
	// }()

	// var fn = func() {
	// 	fmt.Println("这是一个嵌套匿名函数的打印。。。")
	// }
	// fn()

}
